import Vue from 'vue'
import VueRouter from 'vue-router'
import Demo from "@/views/Demo";
import Home from "@/views/Home";
import Red from "@/views/Red";
import Blue from "@/views/Blue";
//注册VueRouter插件
Vue.use(VueRouter)

//路由参数表是一个json数组
const defaultRouters = [
    {
        path: '/',      //path指页面路由地址
        meta:{               //meta指路由的元信息 即描述信息是个json对象(一般回放一些 描述信息/权限信息 等等)
            title:'首页路由'
        },
        name: 'Home',   //name是路由名字
        component: Home  //component 是指向的组件 （component 读音[kəmˈpəʊnənt]）
    },                     //component有2中配置方式  1种是直接指向组件 另一种是懒加载指向组件
    {
        path: '/about',      //访问http://localhost:8080/about即可跳到about组件并显示内容
                             //实际开发中有时会带参数去访问前端路由
                             // 如访问 http://localhost:8080/about?p1=123 ,仍会跳到about组件
                                // 这种?p1=123 的带参访问 在vue中叫 query式带参访问(除此之外还有 params式带参访问,下面的haveParamRouters会讲解)
                             // 此时在about组件可以拿到的router参数有
                             // this.$route.fullPath = /about?p1=123
                             // this.$route.path = /about
                             // this.$route.query.p1 = '123'
                             // this.$route.query = {p1 : '123'}   //query式带参访问拿到参数的方法是用 this.$route.query
                             // this.$route.name = 'About'
                             // this.$route.meta = {title :"About页路由"}
        name: 'About',
        meta:{
            title:'About页路由'
        },
        component: () => import( '../views/About.vue')   //此处为懒加载指向组件
                                                          // (懒加载即只有用户点击触发到该路由时才加载该路由，
                                                        // 前端工程启动时不加载,访问前端首页路由时也不加载,
                                                        // 一般只有做动态路由权限控制时才会用懒加载方式加载路由对应的组件)
    },
    {
        path: '*',         //path配置为*时，即vue匹配不到浏览器输入的路由时，会转到该路由，一般用来显示404页面
        name: '404',
        component: () => import('@/views/404'),
    }
];
const haveParamRouters = [
    {
        path: '/demo/:id',   //path可配置成动态路由
                             //此处的/:id 相当于 springMvc里的 PathVariable (路径变量参数)
        // 此处配置只能以http://localhost:8080/demo/123 访问 (参数不一定是123，反正必须带参数)
        // 访问该路由页面时 this.$route.params.id 的值为123
        // 访问该路由页面时 this.$route.params = {id:"123"}   //params 式带参访问拿到参数的方法是用 this.$route.params
        // 访问该路由页面时 this.$route.params.path 值为 '/demo/123'
        // 访问该路由页面时 this.$route.params.name 值为 'Demo'
        name: 'Demo',
        meta:{
            title:'Demo 页路由'
        },
        component: Demo
    },
    {
        path: '/red/:id?',   //此处配置的/:id? 可以避免出现 像上面的尴尬(只能以http://localhost:8080/demo/123 访问)
                             // 即 是否带参数访问都可以 访问到Red组件并显示内容
                                //这里的? 指匹配的意思,若匹配上了参数，就按带参数访问；若没有匹配上，则直接显示red组件内容
                               //实时的路由参数变化如下
                              // 当以http://localhost:8080/red访问时
                                // this.$route.params.id = undefined  说明页面接收到的参数值为 undefined (未定义)
                                //this.$route.params.path = '/red'
                                //this.$route.params.fullPath = '/red'

                             //当以http://localhost:8080/red/123 访问时
                        // this.$route.params.id = '123'  说明页面接收到的参数值为 123
                        // this.$route.params = {id:"123"}  注意：这里的的参数名是 params ,参数值是json类型
                        //this.$route.params.path = '/red/123'
                        //this.$route.params.fullPath = '/red/123'
        name: 'Red',
        meta:{
            title:'Red 页路由'
        },
        component: Red
    },
    {
        path:'/blue/:id(\\d+)?',  //利用正则表达式限制参数类型为数字
                                   //http://localhost:8080/blue 可以访问到
                                   //http://localhost:8080/blue/123 可以访问到
                                   //http://localhost:8080/blue/qwe123 访问不到
                                   //http://localhost:8080/blue/qwerty 访问不到
        name: 'Blue',
        meta: {
            title:'Blue 页路由'
        },
        component: Blue

    }

];


const router = new VueRouter({
    mode: 'history', //使用h5的history api来切换路由(不带#),浏览器已普遍适配，建议采用这种模式
    // mode: 'hash', //使用哈希模式的api 来切换路由(会带#)
    isAddDynamicMenuRoutes: false, // 是否已经添加动态(菜单)路由,后面会介绍从后端api获取动态路由表
                                    // (即 后端api每次返回的路由表不同，对应前端可访问的路由页面也不同,常用来做 菜单权限控制)
    base: "/", //前端工程访问的根路径 相当于springBoot的servletContextPath
             // (若改成/demo,则首页需要访问http://localhost:8080/demo/,默认配置为/)
    routes: defaultRouters.concat(haveParamRouters)   //此处配置路由参数表,可配置多个路由表concat拼接
})


//全局前置守卫(钩子)
router.beforeEach((to, from, next) => {
    // console.log('即将要进入的目标 路由对象')
    // console.log(to);
    // console.log('当前导航正要离开的路由')
    // console.log(from);
    next();


    //next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。
    //
    // next(): 进行管道中的下一个钩子。如果全部钩子执行完了，则导航的状态就是 confirmed (确认的)。
    //
    // next(false): 中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮)，那么 URL 地址会重置到 from 路由对应的地址。
    //
    // next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。当前的导航被中断，然后进行一个新的导航。你可以向 next 传递任意位置对象，且允许设置诸如 replace: true、name: 'home' 之类的选项以及任何用在 router-link 的 to prop 或 router.push 中的选项。
    //
    // next(error): (2.4.0+) 如果传入 next 的参数是一个 Error 实例，则导航会被终止且该错误会被传递给 router.onError() 注册过的回调

});

//全局后置钩子
//全局后置钩子，然而和前置守卫不同的是，这些钩子不会接受 next 函数也不会改变导航本身
router.afterEach((to, from) => {
    console.log('=start============================')
    console.log('即将要进入的目标 路由对象' + to.fullPath)
    console.log(to);
    console.log('当前导航正要离开的路由' + from.fullPath)
    console.log(from);
    console.log('=end============================')
});


export default router
